package com.example.utils.oss;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;

public class YHUtil {

    private static final Log logger = LogFactory.getLog(YHUtil.class);

    public static boolean stringCompare(String string1, String string2) {
        if (string1 == null) {
            if (string2 == null) {
                return true;
            }
            return false;
        }
        return string1.equalsIgnoreCase(string2);
    }

    public static String stringConcat(String split, String... args) {
        if (args == null) {
            return null;
        }
        if (args.length == 1) {
            return args[0];
        }
        String s = "";
        for (int i = 0; i < args.length; i++) {
            String item = args[i];
            if ((i == 0) || (item.startsWith(split))) {
                s = s.concat(item);
            } else {
                s = s.concat(split + item);
            }
        }
        return s;
    }

    public static boolean stringEndWithIgnoreCase(String string, String end) {
        if ((stringIsNullOrEmpty(string)) || (stringIsNullOrEmpty(end))) {
            return false;
        }
        if (string.length() < end.length()) {
            return false;
        }
        String temp = string.substring(string.length() - end.length());
        return temp.equalsIgnoreCase(end);
    }

    public static boolean stringIsNullOrEmpty(String string) {
        return (string == null) || (string.trim().length() < 1);
    }

    public static String stringReplaceStartChar(String sourceString, String startChar) {
        if ((!stringIsNullOrEmpty(sourceString)) && (!stringIsNullOrEmpty(startChar))) {
            int length = startChar.length();
            while (sourceString.startsWith(startChar)) {
                sourceString = sourceString.substring(length);
            }
        }
        return sourceString;
    }

    public static boolean stringStartWith(String string, String prefix) {
        if ((stringIsNullOrEmpty(string)) || (stringIsNullOrEmpty(prefix))) {
            return false;
        }
        return string.startsWith(prefix);
    }

    public static boolean stringStartWithIgnoreCase(String string, String prefix) {
        if ((stringIsNullOrEmpty(string)) || (stringIsNullOrEmpty(prefix))) {
            return false;
        }
        if (string.length() < prefix.length()) {
            return false;
        }
        String temp = string.substring(0, prefix.length());
        return temp.equalsIgnoreCase(prefix);
    }

    public static String stringSubString(String str, int length) {
        if (str == null) {
            return null;
        }
        if (str.length() > length) {
            return str.substring(0, length);
        }
        return str;
    }

    public static String[] stringSplit(String string, String regex) {
        if ((stringIsNullOrEmpty(string))) {
            return new String[0];
        }
        if (regex == null) {
            return new String[]{string};
        }
        return string.split(regex);
    }

    public static <T> List<T> arrayToList(T[] array) {
        List<T> list = new ArrayList<>();
        if (array == null) {
            return list;
        }
        for (T item : array) {
            list.add(item);
        }
        return list;
    }
    
    public static List<String> StringToList(String string, String regex) {
    	String[] array = stringSplit(string, regex);
    	return arrayToList(array);
    }

    public static boolean stringContains(String string, CharSequence s) {
        if ((stringIsNullOrEmpty(string))) {
            return false;
        }
        return string.contains(s);
    }

    public static boolean toBoolean(String data, boolean defaultValue) {
        try {
            if (data == null) {
                return defaultValue;
            }
            return Boolean.valueOf(data).booleanValue();
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static boolean toBoolean(Object data, boolean defaultValue) {
        try {
            if (data == null) {
                return defaultValue;
            }
            return Boolean.valueOf(String.valueOf(data)).booleanValue();
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static int toInt(Object data, int defaultValue) {
        try {
            if (data == null) {
                return defaultValue;
            }
            return Integer.valueOf(String.valueOf(data)).intValue();
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static int toInt(String data, int defaultValue) {
        try {
            return Integer.valueOf(data).intValue();
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static long toLong(Object data, long defaultValue) {
        try {
            if (data == null) {
                return defaultValue;
            }
            return Long.valueOf(String.valueOf(data));
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static long toLong(String data, long defaultValue) {
        try {
            return Long.valueOf(data);
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static Object objectRead(byte[] bs) throws IOException, ClassNotFoundException {
        ByteArrayInputStream stream = null;
        ObjectInputStream ois = null;
        try {
            stream = new ByteArrayInputStream(bs);
            ois = new ObjectInputStream(stream);
            return ois.readObject();
        } catch (InvalidClassException ex) {
            logger.error(null, ex);
            return null;
        }catch (IOException e){
            logger.error(e);
            return null;
        } finally {
            if (ois != null) {
                ois.close();
            }
            if (stream != null) {
                stream.close();
            }
        }
    }

    public static byte[] objectWrite(Object obj) throws IOException {
        ByteArrayOutputStream stream = null;
        ObjectOutputStream oos = null;
        byte[] bs = null;
        try {
            stream = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(stream);
            oos.writeObject(obj);
            bs = stream.toByteArray();
        } finally {
            if (oos != null) {
                oos.close();
            }
            if (stream != null) {
                stream.close();
            }
        }
        return bs;
    }

    public static String buildUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    public static String objectToJson(Object obj) {
        SerializeConfig config = new SerializeConfig();

        //		config.put(Date.class, new com.fasterxml.jackson.databind.ser.std.DateSerializer());
        return JSONObject.toJSONString(obj, config,
                /* SerializerFeature.WriteNullNumberAsZero, */ SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteNullStringAsEmpty);
    }

    public static <T> T jsonToObject(Class<T> clazz, String json) {
        if (clazz == null || json == null) {
            return null;
        }
        return JSONObject.parseObject(json, clazz);
    }

    public static <T> T jsonToObject(Class<T> clazz, Object obj) {
        if (clazz == null || obj == null) {
            return null;
        }

        if (obj instanceof JSONObject) {
            return jsonToObject(clazz, ((JSONObject) obj).toJSONString());
        } else if (obj instanceof String) {
            return jsonToObject(clazz, (String) obj);
        } else {
            return jsonToObject(clazz, obj.toString());
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> jsonToList(Class<T> clazz, String json) {
        List<T> list = new ArrayList<>();
        if (clazz == null || json == null) {
            return list;
        }
        List<T> temp = JSONObject.parseObject(json, List.class);
        for (T item : temp) {
            if (item != null) {
                if (item instanceof JSONObject) {
                    item = jsonToObject(clazz, ((JSONObject) item).toJSONString());
                } else if (item instanceof String) {
                    item = jsonToObject(clazz, (String) item);
                } else {
                    item = jsonToObject(clazz, item.toString());
                }
            }
            list.add(item);
        }
        return list;
    }

    public static String getFileExtName(String file) {
        if (stringIsNullOrEmpty(file)) {
            return ".";
        }
        file = file.replace(File.separator, "/");
        String[] fs = file.split("/");
        if ((fs != null) && (fs.length > 0)) {
            file = fs[(fs.length - 1)];
        }
        int pos = file.lastIndexOf(".");
        if (pos >= 0) {
            return file.substring(pos);
        }
        return ".";
    }

    public static String getFileName(String path) {
        File f = new File(path);
        return f.getName();
    }

    public static void downloadNetFile(String url, String saveDir, String fileName) {
        try (InputStream ins = new URL(url).openStream()) {
            Path target = Paths.get(saveDir, fileName);
            Files.createDirectories(target.getParent());
            Files.copy(ins, target, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            // TODO抛异常
            logger.error(null, e);
        }
    }

    public static void writeToFile(String file, String data) throws IOException {
        File f = new File(file);
        mkdirs(file);
        if (!f.exists()) {
            mkdirs(file);
            f.createNewFile();
        }
        RandomAccessFile fil = null;
        try {
            fil = new RandomAccessFile(f, "rw");
            long fileLength = fil.length();
            fil.seek(fileLength);
            fil.write(data.getBytes("UTF-8"));
        } finally {
            if (fil != null) {
                fil.close();
            }
        }
    }

    public static void mkdirs(String file) {
        File f = new File(file);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    public static int getDate4Year() {
        Calendar date = Calendar.getInstance();
        return date.get(Calendar.YEAR);
    }

	public static int getDate4Month() {
		Calendar date = Calendar.getInstance();
        return date.get(Calendar.MONTH) + 1;
	}
	
    public static <T> List<T> listSubList(List<T> list, int fromIndex, int toIndex) {
		if (fromIndex < 0) {
			fromIndex = 0;
		}
        if (list == null || fromIndex < 0 || toIndex < 0 || fromIndex > toIndex || list.isEmpty() || fromIndex >= list.size()) {
            return new ArrayList<T>();
        }
        if (toIndex > list.size()) {
            toIndex = list.size();
        }
        return new ArrayList<T>(list.subList(fromIndex, toIndex));
    }

    public static String readRemoteFile(String htmlUrl) {
        int HttpResult; // 服务器返回的状态
        String ee = new String();
        InputStreamReader isReader = null;
        BufferedReader reader = null;
        try {
            URL url = new URL(htmlUrl); // 创建URL
            URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
            urlconn.connect();
            HttpURLConnection httpconn = (HttpURLConnection) urlconn;
            HttpResult = httpconn.getResponseCode();
            if (HttpResult != HttpURLConnection.HTTP_OK) {
                return null;
            } else {
                isReader = new InputStreamReader(urlconn.getInputStream(), "UTF-8");
                reader = new BufferedReader(isReader);
                StringBuffer buffer = new StringBuffer();
                String line; // 用来保存每行读取的内容
                line = reader.readLine(); // 读取第一行
                while (line != null) { // 如果 line 为空说明读完了
                    buffer.append(line); // 将读到的内容添加到 buffer 中
                    buffer.append(" "); // 添加换行符
                    line = reader.readLine(); // 读取下一行
                }
                ee = buffer.toString();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isReader != null) {
                try {
                    isReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ee;
    }

    public static String readRemoteFile(String htmlUrl, String charsetName) {

        int HttpResult; // 服务器返回的状态
        String ee = new String();
        InputStreamReader isReader = null;
        BufferedReader reader = null;
        try {
            URL url = new URL(htmlUrl); // 创建URL
            URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
            urlconn.connect();
            HttpURLConnection httpconn = (HttpURLConnection) urlconn;
            HttpResult = httpconn.getResponseCode();
            if (HttpResult != HttpURLConnection.HTTP_OK) {
                return null;
            } else {
                isReader = new InputStreamReader(urlconn.getInputStream(), charsetName);
                reader = new BufferedReader(isReader);
                StringBuffer buffer = new StringBuffer();
                String line; // 用来保存每行读取的内容
                line = reader.readLine(); // 读取第一行
                while (line != null) { // 如果 line 为空说明读完了
                    buffer.append(line); // 将读到的内容添加到 buffer 中
                    buffer.append(" "); // 添加换行符
                    line = reader.readLine(); // 读取下一行
                }
                ee = buffer.toString();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isReader != null) {
                try {
                    isReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ee;
    }

    public static void main(String[] args) {
        //		String urlPath = "https://yunhenedutest.oss-cn-hangzhou.aliyuncs.com/exam/4/html/2017--2018学年度第二学期第一次阶段性测试英语.html";
        //		String content = readRemoteFile(urlPath);
        //		System.out.println(content);
        //
//        System.out.println(getFileExtName("65c266620c17492d984ba3c519434397/5f2dba9f028c4874a888829a46fc465d.docx"));
//        System.out.println(toBoolean("true", false));
        
        
        String[] items = YHUtil.stringSplit("67.76-85", "\\.");
        System.out.println(items[0]);
    }

    public static <T> String listToString(List<T> list, String split) {
        if (list == null || list.isEmpty()) {
            return "";
        }
        if (split == null) {
            split = ",";
        }
        String str = "";
        int size = list.size();
        for (int i = 0; i < size - 1; i++) {
            str += list.get(i) + split;
        }
        str += list.get(size - 1);
        return str;
    }

    private static String appConfigRoot = "config";
    private static String appRoot = null;

    public static String getAppRoot() {
        if (appRoot == null) {
            String userDir = System.getProperty("user.dir");
            System.out.println("user.dir:" + userDir);
            String webAppDir = System.getProperty("webapp.root");
            System.out.println("webapp.root:" + userDir);
            String config = "config";
            if (stringEndWithIgnoreCase(userDir, File.separator)) {
                userDir = userDir.substring(0, userDir.length() - 1);
            }
            if (stringEndWithIgnoreCase(userDir, File.separator + "bin")) {
                userDir = userDir.substring(0, userDir.length() - 4);
            }
            if (stringEndWithIgnoreCase(webAppDir, File.separator)) {
                webAppDir = webAppDir.substring(0, webAppDir.length() - 1);
            }
            if (stringEndWithIgnoreCase(webAppDir, File.separator + "bin")) {
                webAppDir = webAppDir.substring(0, webAppDir.length() - 4);
            }
            String d = null;
            if ((d == null) && (isExist(userDir + File.separator + config))) {
                d = userDir + File.separator + config;
            }
            if ((d == null) && (isExist(webAppDir + File.separator + config))) {
                d = webAppDir + File.separator + config;
            }
            if (d == null) {
                d = getConfig(YHUtil.class, config);
            }
            if (d == null) {
                d = getConfig(Thread.currentThread().getContextClassLoader(), config);
            }
            if (d == null) {
                config = "conf";
            }
            if ((d == null) && (isExist(userDir + File.separator + config))) {
                d = userDir + File.separator + config;
            }
            if ((d == null) && (isExist(webAppDir + File.separator + config))) {
                d = webAppDir + File.separator + config;
            }
            if (d == null) {
                d = getConfig(YHUtil.class, config);
            }
            if (d == null) {
                d = getConfig(Thread.currentThread().getContextClassLoader(), config);
            }
            if (d == null) {
                try {
                    URL u = YHUtil.class.getResource("/");
                    d = u != null ? u.getPath() : null;
                    appConfigRoot = "config";
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            } else {
                appConfigRoot = config;
            }
            File f = new File(d);
            appRoot = f.getParent();

            String searchStr = File.separator + "WEB-INF";
            int pos = appRoot.indexOf(searchStr);
            if (pos > 0) {
                appRoot = appRoot.substring(0, pos) + searchStr;
            }
            searchStr = File.separator + "data";
            if (appRoot.startsWith(searchStr)) {
                appRoot = appRoot.replace(searchStr, "");
            }
            System.out.println("AppRoot(" + appConfigRoot + "): " + appRoot);
        }
        return appRoot;
    }

    private static String getConfig(Class<?> c, String config) {
        URL url = c.getResource(File.separator + config);
        if (url == null) {
            url = c.getResource("/");
        }
        if (url != null) {
            String d = url.getPath();
            d = d.replace("\\", File.separator);
            d = d.replace("/", File.separator);
            if ((File.separator.equals("\\")) && (d.startsWith(File.separator))) {
                d = d.substring(1);
            }
            if (d.startsWith("file:")) {
                d = d.substring(5);
            }
            System.out.println("getConfig(" + c.getName() + "," + config + "):" + d);
            if ((d.endsWith(File.separator + config + File.separator)) || (d.endsWith(File.separator + config))) {
                return d;
            }
        }
        return getConfig(c.getClassLoader(), config);
    }

    private static String getConfig(ClassLoader c, String config) {
        URL url = c.getResource("");
        if (url != null) {
            String d = url.getPath();
            d = d.replace("\\", File.separator);
            d = d.replace("/", File.separator);
            if ((File.separator.equals("\\")) && (d.startsWith(File.separator))) {
                d = d.substring(1);
            }
            System.out.println("getConfig(Class," + config + "):" + d);
            if (d.startsWith("file:")) {
                d = d.substring(5);
            }
            if ((d.endsWith(File.separator + config + File.separator)) || (d.endsWith(File.separator + config))) {
                return d;
            }
        }
        return null;
    }

    public static boolean isExist(String file) {
        File f = new File(file);
        return (f.isFile()) || (f.isDirectory());
    }

    public static String stringSort(String text) {
        if (text == null) {
            return text;
        }
        char[] arr = text.toCharArray();
        Arrays.sort(arr);
        return new String(arr);
    }

    public static double divisor(Integer val1, Integer val2) {
        if (val1 == null || val2 == null || val2 == 0) {
            return 0.0;
        }
        return val1 / (val2 + 0.0D);
    }

    public static double divisor(Double val1, Integer val2) {
        if (val1 == null || val2 == null || val2 == 0) {
            return 0.0;
        }
        return val1 / (val2 + 0.0D);
    }

    public static double divisor(Double val1, Double val2) {
        if (val1 == null || val2 == null || val2 == 0) {
            return 0.0;
        }
        return val1 / (val2 + 0.0D);
    }

    public static double divisor(Integer val1, Double val2) {
        if (val1 == null || val2 == null || val2 == 0) {
            return 0.0;
        }
        return val1 / (val2 + 0.0D);
    }

    public static boolean compare(Double val1, Double val2) {
        if (val1 == null || val2 == null) {
            return false;
        }
        return val1.equals(val2);
    }

    public static double toDouble(Double value, double defaultValue) {
        return value == null ? defaultValue : value.doubleValue();
    }

    public static double toDouble(Object data, double defaultValue) {
        try {
            if (data == null) {
                return defaultValue;
            }
            return Double.valueOf(String.valueOf(data)).doubleValue();
        } catch (NumberFormatException e) {
            // igonre
        }
        return defaultValue;
    }

    public static String toDateString(Date date, String format) {
        SimpleDateFormat fmt = new SimpleDateFormat(format);
        return fmt.format(date);
    }

    public static boolean equals(Object o1, Object o2) {

        if (o1 == null) {
            if (o2 == null) {
                return true;
            } else {
                return false;
            }
        } else {
            if (o1.equals(o2)) {
                return true;
            } else {
                return false;
            }
        }

    }

	public static <T> Map<String, T> listToKeyObj(List<T> list, String... keys) {
		Map<String, T> map = new LinkedHashMap<>();
		if (list == null || list.isEmpty() || keys == null || keys.length == 0) {
			return map;
		}
		for (T obj : list) {
			if (obj == null) {
				continue;
			}
			String mapKey = getValue(obj, keys);
			if (!stringIsNullOrEmpty(mapKey)) {
				map.put(mapKey, obj);
			}
		}
		return map;
	}
	
	public static <T> Map<String, Map<String, T>> listToKeyMap(List<T> list, String key1, String key2) {
		Map<String, Map<String, T>> map = new LinkedHashMap<>();
		if (list == null || list.isEmpty() || YHUtil.stringIsNullOrEmpty(key1) || YHUtil.stringIsNullOrEmpty(key2)) {
			return map;
		}
		for (T obj : list) {
			if (obj == null) {
				continue;
			}
			String mapKey1 = getValue(obj, key1);
			String mapKey2 = getValue(obj, key2);
			if (!stringIsNullOrEmpty(mapKey1)) {
				Map<String, T> map2 = map.get(mapKey1);
				if(map2==null) {
					map2 = new LinkedHashMap<>();
					map.put(mapKey1, map2);
				}
				map2.put(mapKey2, obj);
			}
		}
		return map;
	}
	
	public static <T> Map<String, List<T>> listToKeyList(List<T> list, String... keys) {
		Map<String, List<T>> map = new LinkedHashMap<>();
		if (list == null || list.isEmpty() || keys == null || keys.length==0) {
			return map;
		}
		for (T obj : list) {
			if (obj == null) {
				continue;
			}
			String mapKey = getValue(obj, keys);
			if (!stringIsNullOrEmpty(mapKey)) {
				List<T> temp = map.get(mapKey);
				if (temp == null) {
					temp = new ArrayList<>();
					map.put(mapKey, temp);
				}
				temp.add(obj);
			}
		}
		return map;
	}

	public static <T, V> List<V> listToValue(Class<V> clazz, List<T> list, String key) {
		List<V> result = new ArrayList<>();
		if (collectionsIsEmpty(list) || stringIsNullOrEmpty(key)) {
			return result;
		}
		
		for (T obj : list) {
			if (obj == null) {
				continue;
			}
			result.add(getValue(clazz, obj, key));
		}
		return result;
	}
	
	public static <T, V> Set<V> listToSValue(Class<V> clazz, List<T> list, String key) {
		Set<V> result = new TreeSet<>();
		if (collectionsIsEmpty(list) || stringIsNullOrEmpty(key)) {
			return result;
		}
		
		for (T obj : list) {
			if (obj == null) {
				continue;
			}
			V value = getValue(clazz, obj, key);
			if (value != null) {
				result.add(value);
			}
		}
		return result;
	}
	
	public static <T, V> V getValue(Class<V> clazz, T obj, String key) {
		if (obj == null || stringIsNullOrEmpty(key)) {
			return null;
		}
		// 将参数命首字母大写
		String newKey = key.substring(0, 1).toUpperCase() + key.substring(1);
		// 通过反射来获取参数的值
		Method m;
		try {
			m = obj.getClass().getMethod("get" + newKey);
			// 获取参数
			Object value = m.invoke(obj);
			if (value != null && clazz.isInstance(value)) {
				return clazz.cast(value);
			} else if(clazz.getName().equals("java.lang.Integer")) {
				return clazz.cast(toInt(value, 0));
			} else {
				return null;
			}
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			throw new BusinessException(ResultEnum.PARAM_ERROR, "");
		}
	}
	
	
	public static <T> String getKey(T obj, String... keys) {
		if (keys == null || keys.length == 0) {
			return "";
		}
		String key = "";
		for (int i = 0; i < keys.length - 1; i++) {
			key += getValue(obj, keys[i]) + "_";
		}
		return key += getValue(obj, keys[keys.length - 1]);
	}
	
	public static <T> String getValue(T obj, String... keys) {
		if (keys == null || keys.length == 0) {
			return "";
		}
		String mapKey = "";
		for (int i = 0; i < keys.length - 1; i++) {
			mapKey += getValue(obj, keys[i]) + "_";
		}
		mapKey += getValue(obj, keys[keys.length - 1]);
		return mapKey;
	}
	
	private static <T> String getValue(T obj, String key) {
		if (obj == null || stringIsNullOrEmpty(key)) {
			return null;
		}
		// 将参数命首字母大写
		String newKey = key.substring(0, 1).toUpperCase() + key.substring(1);
		// 通过反射来获取参数的值
		Method m;
		try {
			m = obj.getClass().getMethod("get" + newKey);
			// 获取参数
			Object value = m.invoke(obj);
			if (value instanceof String) {
				return value.toString();
			} else {
				return String.valueOf(value);
			}
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			throw new BusinessException(ResultEnum.PARAM_ERROR, "");
		}
	}

	
    /**
     * URL乱码转换成中文
     *
     * @param url
     * @return
     */
    public static String unescape(String url) {
        StringBuffer sbuf = new StringBuffer();
        int l = url.length();
        int ch = -1;
        int b, sumb = 0;
        for (int i = 0, more = -1; i < l; i++) {
            /* Get next byte b from URL segment s */
            switch (ch = url.charAt(i)) {
                case '%':
                    ch = url.charAt(++i);
                    int hb = (Character.isDigit((char) ch) ? ch - '0' : 10 + Character.toLowerCase((char) ch) - 'a') & 0xF;
                    ch = url.charAt(++i);
                    int lb = (Character.isDigit((char) ch) ? ch - '0' : 10 + Character.toLowerCase((char) ch) - 'a') & 0xF;
                    b = (hb << 4) | lb;
                    break;
                case '+':
                    b = ' ';
                    break;
                default:
                    b = ch;
            }
            /* Decode byte b as UTF-8, sumb collects incomplete chars */
            if ((b & 0xc0) == 0x80) { // 10xxxxxx (continuation byte)
                sumb = (sumb << 6) | (b & 0x3f); // Add 6 bits to sumb
                if (--more == 0)
                    sbuf.append((char) sumb); // Add char to sbuf
            } else if ((b & 0x80) == 0x00) { // 0xxxxxxx (yields 7 bits)
                sbuf.append((char) b); // Store in sbuf
            } else if ((b & 0xe0) == 0xc0) { // 110xxxxx (yields 5 bits)
                sumb = b & 0x1f;
                more = 1; // Expect 1 more byte
            } else if ((b & 0xf0) == 0xe0) { // 1110xxxx (yields 4 bits)
                sumb = b & 0x0f;
                more = 2; // Expect 2 more bytes
            } else if ((b & 0xf8) == 0xf0) { // 11110xxx (yields 3 bits)
                sumb = b & 0x07;
                more = 3; // Expect 3 more bytes
            } else if ((b & 0xfc) == 0xf8) { // 111110xx (yields 2 bits)
                sumb = b & 0x03;
                more = 4; // Expect 4 more bytes
            } else /* if ((b & 0xfe) == 0xfc) */ { // 1111110x (yields 1 bit)
                sumb = b & 0x01;
                more = 5; // Expect 5 more bytes
            }
            /* We don't test if the UTF-8 encoding is well-formed */
        }
        return sbuf.toString();
    }

    public static <T> List<T> collectionsAdd(List<T> list1, List<T> list2) {
        List<T> result = new ArrayList<>();
        if ((list1 != null) && (!list1.isEmpty())) {
            result.addAll(list1);
        }
        if ((list2 != null) && (!list2.isEmpty())) {
            for (T item : list2) {
                if (!list1.contains(item)) {
                    result.add(item);
                }
            }
        }
        return result;
    }

    public static <T> List<T> collectionsCopy(List<T> list1) {
        List<T> result = new ArrayList<>();
        if ((list1 != null) && (!list1.isEmpty())) {
            result.addAll(list1);
        }
        return result;
    }

    public static <T> List<T> collectionsDecr(List<T> list1, List<T> list2) {
        List<T> result = new ArrayList<>();
        if ((list1 == null) || (list1.isEmpty())) {
            return result;
        }
        if ((list2 != null) && (!list2.isEmpty())) {
            for (T item : list2) {
                if (!list1.contains(item)) {
                    result.add(item);
                }
            }
        }
        return result;
    }

    public static <T> List<T> collectionsRemove(List<T> list1, List<T> list2) {
        List<T> result = new ArrayList<>(list1);
        if ((list1 == null) || (list1.isEmpty())) {
            return result;
        }
        if ((list2 != null) && (!list2.isEmpty())) {
            result.removeAll(list2);
        }
        return result;
    }

    public static <T> List<T> collectionsRemoveNull(List<T> list) {
        List<T> result = new ArrayList<>();
        if ((list != null) && (!list.isEmpty())) {
            for (T item : list) {
                if (item != null) {
                    result.add(item);
                }
            }
        }
        return result;
    }

    public static <T> List<T> collectionsRetain(List<T> list1, List<T> list2) {
        List<T> result = new ArrayList<>();
        if ((list1 == null) || (list2 == null) || (list1.isEmpty()) || (list2.isEmpty())) {
            return result;
        }
        Set<T> set = new HashSet<>(list2);
        for (T item : list1) {
            if (set.contains(item)) {
                result.add(item);
            }
        }
        return result;
    }

    public static <T> void collectionsSetNullPoistion(List<T> list1, List<T> list2) {
        if ((list1 == null) || (list2 == null) || (list1.isEmpty()) || (list2.isEmpty())) {
            return;
        }
        int j = 0;
        for (int i = 0; i < list1.size(); i++) {
            if (list1.get(i) == null) {
                list1.set(i, list2.get(j++));
                if (j >= list2.size()) {
                    return;
                }
            }
        }
    }
    
	public static String getHostAddress() {
			try {
				// 获取操作系统类型
				String sysType = System.getProperties().getProperty("os.name");
				String ip;
				if (sysType.toLowerCase().startsWith("win")) { // 如果是Windows系统，获取本地IP地址
					String localIP = null;
					localIP = InetAddress.getLocalHost().getHostAddress();
					if (localIP != null) {
						return localIP;
					}
				} else {
					ip = getIpByEthNum("eth0"); // 兼容Linux
					if (ip != null) {
						return ip;
					}
				}
			} catch (UnknownHostException e) {
				logger.error(e.getMessage(), e);
			}
		return "127.0.0.1";
	}

	private static String getIpByEthNum(String ethNum) {
		try {
			Enumeration<?> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
			InetAddress ip;
			while (allNetInterfaces.hasMoreElements()) {
				NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
				if (ethNum.equals(netInterface.getName())) {
					Enumeration<?> addresses = netInterface.getInetAddresses();
					while (addresses.hasMoreElements()) {
						ip = (InetAddress) addresses.nextElement();
						if (ip != null && ip instanceof Inet4Address) {
							return ip.getHostAddress();
						}
					}
				}
			}
		} catch (SocketException e) {
			logger.error(e.getMessage(), e);
		}
		return "127.0.0.1";
	}

	public static <T> boolean collectionsIsEmpty(Collection<T> obj) {
		return obj==null || obj.isEmpty();
	}

	public static <T> List<T> toList(T obj) {
		List<T> list = new ArrayList<>();
		list.add(obj);
		return list;
	}
	
	public static <T> List<T> toList(Collection<T> collection) {
		if(collection == null) {
			return new ArrayList<>();
		} else {
			return new ArrayList<>(collection);
		}
	}

	public static <T> T getFirstOne(List<T> list) {
		if(collectionsIsEmpty(list)) {
			return null;
		} else {
			return list.get(0);
		}
	}
	
	public static <T> T getLastOne(List<T> list) {
		if(collectionsIsEmpty(list)) {
			return null;
		} else {
			return list.get(list.size() - 1);
		}
	}

	public static Date beforeDate(int lastDays) {
		Calendar c = Calendar.getInstance();
		int day = c.get(Calendar.DAY_OF_YEAR);
		c.set(Calendar.DAY_OF_YEAR, day - lastDays);
		return c.getTime();
	}

	public static void close(OutputStream output) {
		if (output != null) {
			try {
				output.close();
			} catch (IOException e) {
				// ignore
			}
		}
	}

	public static void close(InputStream in) {
		if (in != null) {
			try {
				in.close();
			} catch (IOException e) {
				// ignore
			}
		}
	}

    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> json2map(String jsonString) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }
    
    
    public static Date getCurrentWeekFirstDay() {
		Calendar calendar = Calendar.getInstance();
	    int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay + 1);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
    public static Date getCurrentWeekLastDay() {
		Calendar calendar = Calendar.getInstance();
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay + 1);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	
	public static Date getPreWeekFirstDay() {
		Calendar calendar = Calendar.getInstance();
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay - 6);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getPreWeekLastDay() {
		Calendar calendar = Calendar.getInstance();
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay - 6);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	public static Date getNextWeekFirstDay() {
		Calendar calendar = Calendar.getInstance();
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay + 8);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getNextWeekLastDay() {
		Calendar calendar = Calendar.getInstance();
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_WEEK);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay + 8);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	public static Date getCurrentMonthFirstDay() {
		Calendar calendar = Calendar.getInstance();
	    int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getCurrentMonthLastDay() {
		Calendar calendar = Calendar.getInstance();
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	public static Date getPreMonthFirstDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) -1);
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getPreMonthLastDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) -1);
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
	
	public static Date getNextMonthFirstDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, firstDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	
	public static Date getNextMonthLastDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	    calendar.set(Calendar.DAY_OF_MONTH, lastDay);
	    calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTime();
	}
}
